#version 450 core

layout(location = 0) in vec4 position;
out vec4 color;

uniform mat4 _MvpMatrix;

layout(binding = 0) uniform sampler2D texSampler;

int random(int seed, int iterations)
{
    int value = seed;
    for(int i = 0; i < iterations; ++i)
    {
        value = ((value >> 7) ^ (value << 9)) * 15485863;
    }
    return value;
}

vec4 randomVec4(int seed)
{
    int r = random(seed, 4);
    int g = random(r, 2);
    int b = random(g, 2);
    int a = random(b, 2);

    return vec4(float(r & 0x3ff) / 1024.0,
                float(g & 0x3ff) / 1024.0,
                float(b & 0x3ff) / 1024.0,
                float(b & 0x3ff) / 1024.0);
}

void main()
{
    vec4 pos = position;
    // scale
    vec4 texColor = texelFetch(texSampler, ivec2(gl_InstanceID & 0x3ff, gl_InstanceID >> 10), 0);
    vec4 scale = vec4(1.0, texColor.r, 1.0, 1.0);
    pos *= scale;

    // rotate
    float cosAngleX = cos(texColor.b);
    float sinAngleX = sin(texColor.b);
    pos.yz = vec2(pos.y * cosAngleX - pos.z * sinAngleX, pos.y * sinAngleX + pos.z * cosAngleX);
    float cosAngleY = cos(texColor.g);
    float sinAngleY = sin(texColor.g);
    pos.xz = vec2(pos.x * cosAngleY + pos.z * sinAngleY, -pos.x * sinAngleY + pos.z * cosAngleY);

    vec4 offset = vec4((gl_InstanceID & 0x3ff) - 512.0, 0.0, (gl_InstanceID >> 10) - 512.0, 0.0);

    // translation
    int number1 = random(gl_InstanceID, 3);
    int number2 = random(number1, 2);
    offset += vec4(float(number1 & 0xff) / 256.0, 0.0, float(number2 & 0xff) / 256.0, 0.0);
    pos += offset;

    gl_Position =_MvpMatrix * pos;
    color = vec4(randomVec4(gl_InstanceID).rgb * vec3(0.1, 0.5, 0.1) + vec3(0.1, 0.4, 0.1), 1.0);
}
